<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>发布订阅模式</title>
    </head>
    <body>
        <script>
            // 可以注册多个事件名称,也可以为一个事件注册多个处理函数
            // Vue内部以对象的形式存储注册的事件

            // 事件触发器
            class EventEmitter {
                constructor() {
                    // 不设置原型的对象方法,可以提高性能
                    // 对象的形式{ 'click': [fn1, fn2], 'change': [fn]}
                    this.subs = Object.create(null);
                }
                // 注册事件(订阅)
                $on(eventType, handler) {
                    // 确保事件类型的值一定是一个数组
                    this.subs[eventType] = this.subs[eventType] || [];
                    // 赋值操作,将事件的处理函数赋值给事件名
                    this.subs[eventType].push(handler);
                }
                // 触发事件(发布)
                $emit(eventType) {
                    if (this.subs[eventType]) {
                        this.subs[eventType].forEach((handler) => {
                            handler();
                        });
                    }
                }
            }
            let em = new EventEmitter();
            // 注册事件(订阅)
            em.$on("dataChange", () => {
                console.log("dataChange1");
            });
            em.$on("dataChange", () => {
                console.log("dataChange2");
            });

            // 触发事件(发布)       
            em.$emit("dataChange");
        </script>
    </body>
</html>
